
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Processes &#8212; libuv documentation</title>
    <link rel="stylesheet" href="../_static/nature.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script src="../_static/jquery.js"></script>
    <script src="../_static/underscore.js"></script>
    <script src="../_static/doctools.js"></script>
    <script src="../_static/language_data.js"></script>
    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Advanced event loops" href="eventloops.html" />
    <link rel="prev" title="Threads" href="threads.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="eventloops.html" title="Advanced event loops"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="threads.html" title="Threads"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">libuv 1.31.0 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../guide.html" accesskey="U">User guide</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">Processes</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="processes">
<h1>Processes<a class="headerlink" href="#processes" title="Permalink to this headline">¶</a></h1>
<p>libuv offers considerable child process management, abstracting the platform
differences and allowing communication with the child process using streams or
named pipes.</p>
<p>A common idiom in Unix is for every process to do one thing and do it well. In
such a case, a process often uses multiple child processes to achieve tasks
(similar to using pipes in shells). A multi-process model with messages
may also be easier to reason about compared to one with threads and shared
memory.</p>
<p>A common refrain against event-based programs is that they cannot take
advantage of multiple cores in modern computers. In a multi-threaded program
the kernel can perform scheduling and assign different threads to different
cores, improving performance. But an event loop has only one thread.  The
workaround can be to launch multiple processes instead, with each process
running an event loop, and each process getting assigned to a separate CPU
core.</p>
<div class="section" id="spawning-child-processes">
<h2>Spawning child processes<a class="headerlink" href="#spawning-child-processes" title="Permalink to this headline">¶</a></h2>
<p>The simplest case is when you simply want to launch a process and know when it
exits. This is achieved using <code class="docutils literal notranslate"><span class="pre">uv_spawn</span></code>.</p>
<p class="rubric">spawn/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">uv_loop_t</span> <span class="o">*</span><span class="n">loop</span><span class="p">;</span>
<span class="n">uv_process_t</span> <span class="n">child_req</span><span class="p">;</span>
<span class="n">uv_process_options_t</span> <span class="n">options</span><span class="p">;</span>
<span class="nb">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">uv_default_loop</span><span class="p">();</span>

    <span class="n">char</span><span class="o">*</span> <span class="n">args</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
    <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;mkdir&quot;</span><span class="p">;</span>
    <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;test-dir&quot;</span><span class="p">;</span>
    <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">NULL</span><span class="p">;</span>
<span class="hll">
</span>    <span class="n">options</span><span class="o">.</span><span class="n">exit_cb</span> <span class="o">=</span> <span class="n">on_exit</span><span class="p">;</span>
<span class="hll">    <span class="n">options</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="s2">&quot;mkdir&quot;</span><span class="p">;</span>
</span><span class="hll">    <span class="n">options</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="p">;</span>
</span><span class="hll">
</span><span class="hll">    <span class="nb">int</span> <span class="n">r</span><span class="p">;</span>
</span><span class="hll">    <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">uv_spawn</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">child_req</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">options</span><span class="p">)))</span> <span class="p">{</span>
</span>        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">uv_strerror</span><span class="p">(</span><span class="n">r</span><span class="p">));</span>
        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;Launched process with ID </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">child_req</span><span class="o">.</span><span class="n">pid</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">uv_run</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="n">UV_RUN_DEFAULT</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">options</span></code> is implicitly initialized with zeros since it is a global
variable.  If you change <code class="docutils literal notranslate"><span class="pre">options</span></code> to a local variable, remember to
initialize it to null out all unused fields:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">uv_process_options_t</span> <span class="n">options</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</pre></div>
</div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">uv_process_t</span></code> struct only acts as the handle, all options are set via
<code class="docutils literal notranslate"><span class="pre">uv_process_options_t</span></code>. To simply launch a process, you need to set only the
<code class="docutils literal notranslate"><span class="pre">file</span></code> and <code class="docutils literal notranslate"><span class="pre">args</span></code> fields. <code class="docutils literal notranslate"><span class="pre">file</span></code> is the program to execute. Since
<code class="docutils literal notranslate"><span class="pre">uv_spawn</span></code> uses <a class="reference external" href="http://www.kernel.org/doc/man-pages/online/pages/man3/exec.3.html">execvp</a> internally, there is no need to supply the full
path. Finally as per underlying conventions, <strong>the arguments array has to be
one larger than the number of arguments, with the last element being NULL</strong>.</p>
<p>After the call to <code class="docutils literal notranslate"><span class="pre">uv_spawn</span></code>, <code class="docutils literal notranslate"><span class="pre">uv_process_t.pid</span></code> will contain the process
ID of the child process.</p>
<p>The exit callback will be invoked with the <em>exit status</em> and the type of <em>signal</em>
which caused the exit.</p>
<p class="rubric">spawn/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="highlight"><pre><span></span>
<span class="n">void</span> <span class="n">on_exit</span><span class="p">(</span><span class="n">uv_process_t</span> <span class="o">*</span><span class="n">req</span><span class="p">,</span> <span class="n">int64_t</span> <span class="n">exit_status</span><span class="p">,</span> <span class="nb">int</span> <span class="n">term_signal</span><span class="p">)</span> <span class="p">{</span>
<span class="hll">    <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;Process exited with status %&quot;</span> <span class="n">PRId64</span> <span class="s2">&quot;, signal </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">exit_status</span><span class="p">,</span> <span class="n">term_signal</span><span class="p">);</span>
</span>    <span class="n">uv_close</span><span class="p">((</span><span class="n">uv_handle_t</span><span class="o">*</span><span class="p">)</span> <span class="n">req</span><span class="p">,</span> <span class="n">NULL</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>It is <strong>required</strong> to close the process watcher after the process exits.</p>
</div>
<div class="section" id="changing-process-parameters">
<h2>Changing process parameters<a class="headerlink" href="#changing-process-parameters" title="Permalink to this headline">¶</a></h2>
<p>Before the child process is launched you can control the execution environment
using fields in <code class="docutils literal notranslate"><span class="pre">uv_process_options_t</span></code>.</p>
<div class="section" id="change-execution-directory">
<h3>Change execution directory<a class="headerlink" href="#change-execution-directory" title="Permalink to this headline">¶</a></h3>
<p>Set <code class="docutils literal notranslate"><span class="pre">uv_process_options_t.cwd</span></code> to the corresponding directory.</p>
</div>
<div class="section" id="set-environment-variables">
<h3>Set environment variables<a class="headerlink" href="#set-environment-variables" title="Permalink to this headline">¶</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">uv_process_options_t.env</span></code> is a null-terminated array of strings, each of the
form <code class="docutils literal notranslate"><span class="pre">VAR=VALUE</span></code> used to set up the environment variables for the process. Set
this to <code class="docutils literal notranslate"><span class="pre">NULL</span></code> to inherit the environment from the parent (this) process.</p>
</div>
<div class="section" id="option-flags">
<h3>Option flags<a class="headerlink" href="#option-flags" title="Permalink to this headline">¶</a></h3>
<p>Setting <code class="docutils literal notranslate"><span class="pre">uv_process_options_t.flags</span></code> to a bitwise OR of the following flags,
modifies the child process behaviour:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">UV_PROCESS_SETUID</span></code> - sets the child’s execution user ID to <code class="docutils literal notranslate"><span class="pre">uv_process_options_t.uid</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">UV_PROCESS_SETGID</span></code> - sets the child’s execution group ID to <code class="docutils literal notranslate"><span class="pre">uv_process_options_t.gid</span></code>.</p></li>
</ul>
<p>Changing the UID/GID is only supported on Unix, <code class="docutils literal notranslate"><span class="pre">uv_spawn</span></code> will fail on
Windows with <code class="docutils literal notranslate"><span class="pre">UV_ENOTSUP</span></code>.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS</span></code> - No quoting or escaping of
<code class="docutils literal notranslate"><span class="pre">uv_process_options_t.args</span></code> is done on Windows. Ignored on Unix.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">UV_PROCESS_DETACHED</span></code> - Starts the child process in a new session, which
will keep running after the parent process exits. See example below.</p></li>
</ul>
</div>
</div>
<div class="section" id="detaching-processes">
<h2>Detaching processes<a class="headerlink" href="#detaching-processes" title="Permalink to this headline">¶</a></h2>
<p>Passing the flag <code class="docutils literal notranslate"><span class="pre">UV_PROCESS_DETACHED</span></code> can be used to launch daemons, or
child processes which are independent of the parent so that the parent exiting
does not affect it.</p>
<p class="rubric">detach/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="nb">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">uv_default_loop</span><span class="p">();</span>

    <span class="n">char</span><span class="o">*</span> <span class="n">args</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
    <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;sleep&quot;</span><span class="p">;</span>
    <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;100&quot;</span><span class="p">;</span>
    <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">NULL</span><span class="p">;</span>

    <span class="n">options</span><span class="o">.</span><span class="n">exit_cb</span> <span class="o">=</span> <span class="n">NULL</span><span class="p">;</span>
    <span class="n">options</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="s2">&quot;sleep&quot;</span><span class="p">;</span>
    <span class="n">options</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="p">;</span>
<span class="hll">    <span class="n">options</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_PROCESS_DETACHED</span><span class="p">;</span>
</span>
    <span class="nb">int</span> <span class="n">r</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">uv_spawn</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">child_req</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">options</span><span class="p">)))</span> <span class="p">{</span>
        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">uv_strerror</span><span class="p">(</span><span class="n">r</span><span class="p">));</span>
        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
<span class="hll">    <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;Launched sleep with PID </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">child_req</span><span class="o">.</span><span class="n">pid</span><span class="p">);</span>
</span>    <span class="n">uv_unref</span><span class="p">((</span><span class="n">uv_handle_t</span><span class="o">*</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">child_req</span><span class="p">);</span>

    <span class="k">return</span> <span class="n">uv_run</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="n">UV_RUN_DEFAULT</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>Just remember that the handle is still monitoring the child, so your program
won’t exit. Use <code class="docutils literal notranslate"><span class="pre">uv_unref()</span></code> if you want to be more <em>fire-and-forget</em>.</p>
</div>
<div class="section" id="sending-signals-to-processes">
<h2>Sending signals to processes<a class="headerlink" href="#sending-signals-to-processes" title="Permalink to this headline">¶</a></h2>
<p>libuv wraps the standard <code class="docutils literal notranslate"><span class="pre">kill(2)</span></code> system call on Unix and implements one
with similar semantics on Windows, with <em>one caveat</em>: all of <code class="docutils literal notranslate"><span class="pre">SIGTERM</span></code>,
<code class="docutils literal notranslate"><span class="pre">SIGINT</span></code> and <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code>, lead to termination of the process. The signature
of <code class="docutils literal notranslate"><span class="pre">uv_kill</span></code> is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">uv_err_t</span> <span class="n">uv_kill</span><span class="p">(</span><span class="nb">int</span> <span class="n">pid</span><span class="p">,</span> <span class="nb">int</span> <span class="n">signum</span><span class="p">);</span>
</pre></div>
</div>
<p>For processes started using libuv, you may use <code class="docutils literal notranslate"><span class="pre">uv_process_kill</span></code> instead,
which accepts the <code class="docutils literal notranslate"><span class="pre">uv_process_t</span></code> watcher as the first argument, rather than
the pid. In this case, <strong>remember to call</strong> <code class="docutils literal notranslate"><span class="pre">uv_close</span></code> on the watcher.</p>
</div>
<div class="section" id="signals">
<h2>Signals<a class="headerlink" href="#signals" title="Permalink to this headline">¶</a></h2>
<p>libuv provides wrappers around Unix signals with <a class="reference external" href="http://docs.libuv.org/en/v1.x/signal.html#signal">some Windows support</a> as well.</p>
<p>Use <code class="docutils literal notranslate"><span class="pre">uv_signal_init()</span></code> to initialize
a handle and associate it with a loop. To listen for particular signals on
that handler, use <code class="docutils literal notranslate"><span class="pre">uv_signal_start()</span></code> with the handler function. Each handler
can only be associated with one signal number, with subsequent calls to
<code class="docutils literal notranslate"><span class="pre">uv_signal_start()</span></code> overwriting earlier associations. Use <code class="docutils literal notranslate"><span class="pre">uv_signal_stop()</span></code> to
stop watching. Here is a small example demonstrating the various possibilities:</p>
<p class="rubric">signal/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">#include &lt;stdio.h&gt;</span>
<span class="c1">#include &lt;stdlib.h&gt;</span>
<span class="c1">#include &lt;unistd.h&gt;</span>
<span class="c1">#include &lt;uv.h&gt;</span>

<span class="n">uv_loop_t</span><span class="o">*</span> <span class="n">create_loop</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">uv_loop_t</span> <span class="o">*</span><span class="n">loop</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="n">sizeof</span><span class="p">(</span><span class="n">uv_loop_t</span><span class="p">));</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">loop</span><span class="p">)</span> <span class="p">{</span>
      <span class="n">uv_loop_init</span><span class="p">(</span><span class="n">loop</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">loop</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">void</span> <span class="n">signal_handler</span><span class="p">(</span><span class="n">uv_signal_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="nb">int</span> <span class="n">signum</span><span class="p">)</span>
<span class="p">{</span>
<span class="hll">    <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;Signal received: </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">signum</span><span class="p">);</span>
</span><span class="hll">    <span class="n">uv_signal_stop</span><span class="p">(</span><span class="n">handle</span><span class="p">);</span>
</span><span class="p">}</span>

<span class="o">//</span> <span class="n">two</span> <span class="n">signal</span> <span class="n">handlers</span> <span class="ow">in</span> <span class="n">one</span> <span class="n">loop</span>
<span class="n">void</span> <span class="n">thread1_worker</span><span class="p">(</span><span class="n">void</span> <span class="o">*</span><span class="n">userp</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">uv_loop_t</span> <span class="o">*</span><span class="n">loop1</span> <span class="o">=</span> <span class="n">create_loop</span><span class="p">();</span>

    <span class="n">uv_signal_t</span> <span class="n">sig1a</span><span class="p">,</span> <span class="n">sig1b</span><span class="p">;</span>
<span class="hll">    <span class="n">uv_signal_init</span><span class="p">(</span><span class="n">loop1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sig1a</span><span class="p">);</span>
</span><span class="hll">    <span class="n">uv_signal_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sig1a</span><span class="p">,</span> <span class="n">signal_handler</span><span class="p">,</span> <span class="n">SIGUSR1</span><span class="p">);</span>
</span>
    <span class="n">uv_signal_init</span><span class="p">(</span><span class="n">loop1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sig1b</span><span class="p">);</span>
    <span class="n">uv_signal_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sig1b</span><span class="p">,</span> <span class="n">signal_handler</span><span class="p">,</span> <span class="n">SIGUSR1</span><span class="p">);</span>

    <span class="n">uv_run</span><span class="p">(</span><span class="n">loop1</span><span class="p">,</span> <span class="n">UV_RUN_DEFAULT</span><span class="p">);</span>
<span class="p">}</span>

<span class="o">//</span> <span class="n">two</span> <span class="n">signal</span> <span class="n">handlers</span><span class="p">,</span> <span class="n">each</span> <span class="ow">in</span> <span class="n">its</span> <span class="n">own</span> <span class="n">loop</span>
<span class="n">void</span> <span class="n">thread2_worker</span><span class="p">(</span><span class="n">void</span> <span class="o">*</span><span class="n">userp</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">uv_loop_t</span> <span class="o">*</span><span class="n">loop2</span> <span class="o">=</span> <span class="n">create_loop</span><span class="p">();</span>
    <span class="n">uv_loop_t</span> <span class="o">*</span><span class="n">loop3</span> <span class="o">=</span> <span class="n">create_loop</span><span class="p">();</span>

    <span class="n">uv_signal_t</span> <span class="n">sig2</span><span class="p">;</span>
    <span class="n">uv_signal_init</span><span class="p">(</span><span class="n">loop2</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sig2</span><span class="p">);</span>
    <span class="n">uv_signal_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sig2</span><span class="p">,</span> <span class="n">signal_handler</span><span class="p">,</span> <span class="n">SIGUSR1</span><span class="p">);</span>

    <span class="n">uv_signal_t</span> <span class="n">sig3</span><span class="p">;</span>
    <span class="n">uv_signal_init</span><span class="p">(</span><span class="n">loop3</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sig3</span><span class="p">);</span>
    <span class="n">uv_signal_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sig3</span><span class="p">,</span> <span class="n">signal_handler</span><span class="p">,</span> <span class="n">SIGUSR1</span><span class="p">);</span>

    <span class="k">while</span> <span class="p">(</span><span class="n">uv_run</span><span class="p">(</span><span class="n">loop2</span><span class="p">,</span> <span class="n">UV_RUN_NOWAIT</span><span class="p">)</span> <span class="o">||</span> <span class="n">uv_run</span><span class="p">(</span><span class="n">loop3</span><span class="p">,</span> <span class="n">UV_RUN_NOWAIT</span><span class="p">))</span> <span class="p">{</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nb">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;PID </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">getpid</span><span class="p">());</span>

    <span class="n">uv_thread_t</span> <span class="n">thread1</span><span class="p">,</span> <span class="n">thread2</span><span class="p">;</span>

    <span class="n">uv_thread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">thread1</span><span class="p">,</span> <span class="n">thread1_worker</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
    <span class="n">uv_thread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">thread2</span><span class="p">,</span> <span class="n">thread2_worker</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>

    <span class="n">uv_thread_join</span><span class="p">(</span><span class="o">&amp;</span><span class="n">thread1</span><span class="p">);</span>
    <span class="n">uv_thread_join</span><span class="p">(</span><span class="o">&amp;</span><span class="n">thread2</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">uv_run(loop,</span> <span class="pre">UV_RUN_NOWAIT)</span></code> is similar to <code class="docutils literal notranslate"><span class="pre">uv_run(loop,</span> <span class="pre">UV_RUN_ONCE)</span></code>
in that it will process only one event. UV_RUN_ONCE blocks if there are no
pending events, while UV_RUN_NOWAIT will return immediately. We use NOWAIT
so that one of the loops isn’t starved because the other one has no pending
activity.</p>
</div>
<p>Send <code class="docutils literal notranslate"><span class="pre">SIGUSR1</span></code> to the process, and you’ll find the handler being invoked
4 times, one for each <code class="docutils literal notranslate"><span class="pre">uv_signal_t</span></code>. The handler just stops each handle,
so that the program exits. This sort of dispatch to all handlers is very
useful. A server using multiple event loops could ensure that all data was
safely saved before termination, simply by every loop adding a watcher for
<code class="docutils literal notranslate"><span class="pre">SIGINT</span></code>.</p>
</div>
<div class="section" id="child-process-i-o">
<h2>Child Process I/O<a class="headerlink" href="#child-process-i-o" title="Permalink to this headline">¶</a></h2>
<p>A normal, newly spawned process has its own set of file descriptors, with 0,
1 and 2 being <code class="docutils literal notranslate"><span class="pre">stdin</span></code>, <code class="docutils literal notranslate"><span class="pre">stdout</span></code> and <code class="docutils literal notranslate"><span class="pre">stderr</span></code> respectively. Sometimes you
may want to share file descriptors with the child. For example, perhaps your
applications launches a sub-command and you want any errors to go in the log
file, but ignore <code class="docutils literal notranslate"><span class="pre">stdout</span></code>. For this you’d like to have <code class="docutils literal notranslate"><span class="pre">stderr</span></code> of the
child be the same as the stderr of the parent. In this case, libuv supports
<em>inheriting</em> file descriptors. In this sample, we invoke the test program,
which is:</p>
<p class="rubric">proc-streams/test.c</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#include &lt;stdio.h&gt;</span>

<span class="nb">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;This is stderr</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;This is stdout</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The actual program <code class="docutils literal notranslate"><span class="pre">proc-streams</span></code> runs this while sharing only <code class="docutils literal notranslate"><span class="pre">stderr</span></code>.
The file descriptors of the child process are set using the <code class="docutils literal notranslate"><span class="pre">stdio</span></code> field in
<code class="docutils literal notranslate"><span class="pre">uv_process_options_t</span></code>. First set the <code class="docutils literal notranslate"><span class="pre">stdio_count</span></code> field to the number of
file descriptors being set. <code class="docutils literal notranslate"><span class="pre">uv_process_options_t.stdio</span></code> is an array of
<code class="docutils literal notranslate"><span class="pre">uv_stdio_container_t</span></code>, which is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">*</span>
 <span class="o">*</span> <span class="n">Request</span> <span class="nb">object</span> <span class="k">for</span> <span class="n">uv_getaddrinfo</span><span class="o">.</span>
 <span class="o">*/</span>
<span class="n">struct</span> <span class="n">uv_getaddrinfo_s</span> <span class="p">{</span>
  <span class="n">UV_REQ_FIELDS</span>
  <span class="o">/*</span> <span class="n">read</span><span class="o">-</span><span class="n">only</span> <span class="o">*/</span>
  <span class="n">uv_loop_t</span><span class="o">*</span> <span class="n">loop</span><span class="p">;</span>
  <span class="o">/*</span> <span class="n">struct</span> <span class="n">addrinfo</span><span class="o">*</span> <span class="n">addrinfo</span> <span class="ow">is</span> <span class="n">marked</span> <span class="k">as</span> <span class="n">private</span><span class="p">,</span> <span class="n">but</span> <span class="n">it</span> <span class="n">really</span> <span class="n">isn</span><span class="s1">&#39;t. */</span>
  <span class="n">UV_GETADDRINFO_PRIVATE_FIELDS</span>
</pre></div>
</div>
<p>where flags can have several values. Use <code class="docutils literal notranslate"><span class="pre">UV_IGNORE</span></code> if it isn’t going to be
used. If the first three <code class="docutils literal notranslate"><span class="pre">stdio</span></code> fields are marked as <code class="docutils literal notranslate"><span class="pre">UV_IGNORE</span></code> they’ll
redirect to <code class="docutils literal notranslate"><span class="pre">/dev/null</span></code>.</p>
<p>Since we want to pass on an existing descriptor, we’ll use <code class="docutils literal notranslate"><span class="pre">UV_INHERIT_FD</span></code>.
Then we set the <code class="docutils literal notranslate"><span class="pre">fd</span></code> to <code class="docutils literal notranslate"><span class="pre">stderr</span></code>.</p>
<p class="rubric">proc-streams/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26</pre></div></td><td class="code"><div class="highlight"><pre><span></span>
<span class="nb">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">uv_default_loop</span><span class="p">();</span>

    <span class="o">/*</span> <span class="o">...</span> <span class="o">*/</span>
<span class="hll">
</span>    <span class="n">options</span><span class="o">.</span><span class="n">stdio_count</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="n">uv_stdio_container_t</span> <span class="n">child_stdio</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_IGNORE</span><span class="p">;</span>
<span class="hll">    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_IGNORE</span><span class="p">;</span>
</span><span class="hll">    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_INHERIT_FD</span><span class="p">;</span>
</span><span class="hll">    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">fd</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
</span>    <span class="n">options</span><span class="o">.</span><span class="n">stdio</span> <span class="o">=</span> <span class="n">child_stdio</span><span class="p">;</span>

    <span class="n">options</span><span class="o">.</span><span class="n">exit_cb</span> <span class="o">=</span> <span class="n">on_exit</span><span class="p">;</span>
    <span class="n">options</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
    <span class="n">options</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="p">;</span>

    <span class="nb">int</span> <span class="n">r</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">uv_spawn</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">child_req</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">options</span><span class="p">)))</span> <span class="p">{</span>
        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">uv_strerror</span><span class="p">(</span><span class="n">r</span><span class="p">));</span>
        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">uv_run</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="n">UV_RUN_DEFAULT</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>If you run <code class="docutils literal notranslate"><span class="pre">proc-stream</span></code> you’ll see that only the line “This is stderr” will
be displayed. Try marking <code class="docutils literal notranslate"><span class="pre">stdout</span></code> as being inherited and see the output.</p>
<p>It is dead simple to apply this redirection to streams.  By setting <code class="docutils literal notranslate"><span class="pre">flags</span></code>
to <code class="docutils literal notranslate"><span class="pre">UV_INHERIT_STREAM</span></code> and setting <code class="docutils literal notranslate"><span class="pre">data.stream</span></code> to the stream in the
parent process, the child process can treat that stream as standard I/O. This
can be used to implement something like <a class="reference external" href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a>.</p>
<p>A sample CGI script/executable is:</p>
<p class="rubric">cgi/tick.c</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#include &lt;stdio.h&gt;</span>
<span class="c1">#include &lt;unistd.h&gt;</span>

<span class="nb">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="nb">int</span> <span class="n">i</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;tick</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
        <span class="n">fflush</span><span class="p">(</span><span class="n">stdout</span><span class="p">);</span>
        <span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;BOOM!</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The CGI server combines the concepts from this chapter and <a class="reference internal" href="networking.html"><span class="doc">Networking</span></a> so
that every client is sent ten ticks after which that connection is closed.</p>
<p class="rubric">cgi/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="highlight"><pre><span></span>
void on_new_connection(uv_stream_t *server, int status) {
    if (status == -1) {
        // error!
        return;
    }

    uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop, client);
<span class="hll">    if (uv_accept(server, (uv_stream_t*) client) == 0) {
</span>        invoke_cgi_script(client);
    }
    else {
        uv_close((uv_handle_t*) client, NULL);
    }
</pre></div>
</td></tr></table></div>
<p>Here we simply accept the TCP connection and pass on the socket (<em>stream</em>) to
<code class="docutils literal notranslate"><span class="pre">invoke_cgi_script</span></code>.</p>
<p class="rubric">cgi/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre></div></td><td class="code"><div class="highlight"><pre><span></span>
    <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">NULL</span><span class="p">;</span>

    <span class="o">/*</span> <span class="o">...</span> <span class="n">finding</span> <span class="n">the</span> <span class="n">executable</span> <span class="n">path</span> <span class="ow">and</span> <span class="n">setting</span> <span class="n">up</span> <span class="n">arguments</span> <span class="o">...</span> <span class="o">*/</span>

    <span class="n">options</span><span class="o">.</span><span class="n">stdio_count</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="n">uv_stdio_container_t</span> <span class="n">child_stdio</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
<span class="hll">    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_IGNORE</span><span class="p">;</span>
</span><span class="hll">    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_INHERIT_STREAM</span><span class="p">;</span>
</span>    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="p">(</span><span class="n">uv_stream_t</span><span class="o">*</span><span class="p">)</span> <span class="n">client</span><span class="p">;</span>
    <span class="n">child_stdio</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_IGNORE</span><span class="p">;</span>
    <span class="n">options</span><span class="o">.</span><span class="n">stdio</span> <span class="o">=</span> <span class="n">child_stdio</span><span class="p">;</span>

    <span class="n">options</span><span class="o">.</span><span class="n">exit_cb</span> <span class="o">=</span> <span class="n">cleanup_handles</span><span class="p">;</span>
    <span class="n">options</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
    <span class="n">options</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="p">;</span>

<span class="hll">    <span class="o">//</span> <span class="n">Set</span> <span class="n">this</span> <span class="n">so</span> <span class="n">we</span> <span class="n">can</span> <span class="n">close</span> <span class="n">the</span> <span class="n">socket</span> <span class="n">after</span> <span class="n">the</span> <span class="n">child</span> <span class="n">process</span> <span class="n">exits</span><span class="o">.</span>
</span>    <span class="n">child_req</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">(</span><span class="n">void</span><span class="o">*</span><span class="p">)</span> <span class="n">client</span><span class="p">;</span>
<span class="hll">    <span class="nb">int</span> <span class="n">r</span><span class="p">;</span>
</span>    <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">uv_spawn</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">child_req</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">options</span><span class="p">)))</span> <span class="p">{</span>
        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">uv_strerror</span><span class="p">(</span><span class="n">r</span><span class="p">));</span>
</pre></div>
</td></tr></table></div>
<p>The <code class="docutils literal notranslate"><span class="pre">stdout</span></code> of the CGI script is set to the socket so that whatever our tick
script prints, gets sent to the client. By using processes, we can offload the
read/write buffering to the operating system, so in terms of convenience this
is great. Just be warned that creating processes is a costly task.</p>
</div>
<div class="section" id="pipes">
<span id="id1"></span><h2>Pipes<a class="headerlink" href="#pipes" title="Permalink to this headline">¶</a></h2>
<p>libuv’s <code class="docutils literal notranslate"><span class="pre">uv_pipe_t</span></code> structure is slightly confusing to Unix programmers,
because it immediately conjures up <code class="docutils literal notranslate"><span class="pre">|</span></code> and <a class="reference external" href="http://www.kernel.org/doc/man-pages/online/pages/man7/pipe.7.html">pipe(7)</a>. But <code class="docutils literal notranslate"><span class="pre">uv_pipe_t</span></code> is
not related to anonymous pipes, rather it is an IPC mechanism. <code class="docutils literal notranslate"><span class="pre">uv_pipe_t</span></code>
can be backed by a <a class="reference external" href="http://www.kernel.org/doc/man-pages/online/pages/man7/unix.7.html">Unix Domain Socket</a> or <a class="reference external" href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365590(v=vs.85).aspx">Windows Named Pipe</a> to allow
multiple processes to communicate. This is discussed below.</p>
<div class="section" id="parent-child-ipc">
<h3>Parent-child IPC<a class="headerlink" href="#parent-child-ipc" title="Permalink to this headline">¶</a></h3>
<p>A parent and child can have one or two way communication over a pipe created by
settings <code class="docutils literal notranslate"><span class="pre">uv_stdio_container_t.flags</span></code> to a bit-wise combination of
<code class="docutils literal notranslate"><span class="pre">UV_CREATE_PIPE</span></code> and <code class="docutils literal notranslate"><span class="pre">UV_READABLE_PIPE</span></code> or <code class="docutils literal notranslate"><span class="pre">UV_WRITABLE_PIPE</span></code>. The
read/write flag is from the perspective of the child process.</p>
</div>
<div class="section" id="arbitrary-process-ipc">
<h3>Arbitrary process IPC<a class="headerlink" href="#arbitrary-process-ipc" title="Permalink to this headline">¶</a></h3>
<p>Since domain sockets <a class="footnote-reference brackets" href="#id3" id="id2">1</a> can have a well known name and a location in the
file-system they can be used for IPC between unrelated processes. The <a class="reference external" href="http://www.freedesktop.org/wiki/Software/dbus">D-BUS</a>
system used by open source desktop environments uses domain sockets for event
notification. Various applications can then react when a contact comes online
or new hardware is detected. The MySQL server also runs a domain socket on
which clients can interact with it.</p>
<p>When using domain sockets, a client-server pattern is usually followed with the
creator/owner of the socket acting as the server. After the initial setup,
messaging is no different from TCP, so we’ll re-use the echo server example.</p>
<p class="rubric">pipe-echo-server/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">void</span> <span class="n">remove_sock</span><span class="p">(</span><span class="nb">int</span> <span class="n">sig</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">uv_fs_t</span> <span class="n">req</span><span class="p">;</span>
    <span class="n">uv_fs_unlink</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">req</span><span class="p">,</span> <span class="n">PIPENAME</span><span class="p">,</span> <span class="n">NULL</span><span class="p">);</span>
    <span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="hll"><span class="p">}</span>
</span>
<span class="nb">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">uv_default_loop</span><span class="p">();</span>

<span class="hll">    <span class="n">uv_pipe_t</span> <span class="n">server</span><span class="p">;</span>
</span>    <span class="n">uv_pipe_init</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">server</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>

    <span class="n">signal</span><span class="p">(</span><span class="n">SIGINT</span><span class="p">,</span> <span class="n">remove_sock</span><span class="p">);</span>
<span class="hll">
</span>    <span class="nb">int</span> <span class="n">r</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">uv_pipe_bind</span><span class="p">(</span><span class="o">&amp;</span><span class="n">server</span><span class="p">,</span> <span class="n">PIPENAME</span><span class="p">)))</span> <span class="p">{</span>
        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;Bind error </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">uv_err_name</span><span class="p">(</span><span class="n">r</span><span class="p">));</span>
        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">uv_listen</span><span class="p">((</span><span class="n">uv_stream_t</span><span class="o">*</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">server</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="n">on_new_connection</span><span class="p">)))</span> <span class="p">{</span>
        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;Listen error </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">uv_err_name</span><span class="p">(</span><span class="n">r</span><span class="p">));</span>
        <span class="k">return</span> <span class="mi">2</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">uv_run</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="n">UV_RUN_DEFAULT</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>We name the socket <code class="docutils literal notranslate"><span class="pre">echo.sock</span></code> which means it will be created in the local
directory. This socket now behaves no different from TCP sockets as far as
the stream API is concerned. You can test this server using <a class="reference external" href="http://www.dest-unreach.org/socat/">socat</a>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ socat - /path/to/socket
</pre></div>
</div>
<p>A client which wants to connect to a domain socket will use:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">void</span> <span class="n">uv_pipe_connect</span><span class="p">(</span><span class="n">uv_connect_t</span> <span class="o">*</span><span class="n">req</span><span class="p">,</span> <span class="n">uv_pipe_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="n">const</span> <span class="n">char</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="n">uv_connect_cb</span> <span class="n">cb</span><span class="p">);</span>
</pre></div>
</div>
<p>where <code class="docutils literal notranslate"><span class="pre">name</span></code> will be <code class="docutils literal notranslate"><span class="pre">echo.sock</span></code> or similar. On Unix systems, <code class="docutils literal notranslate"><span class="pre">name</span></code> must
point to a valid file (e.g. <code class="docutils literal notranslate"><span class="pre">/tmp/echo.sock</span></code>). On Windows, <code class="docutils literal notranslate"><span class="pre">name</span></code> follows a
<code class="docutils literal notranslate"><span class="pre">\\?\pipe\echo.sock</span></code> format.</p>
</div>
<div class="section" id="sending-file-descriptors-over-pipes">
<h3>Sending file descriptors over pipes<a class="headerlink" href="#sending-file-descriptors-over-pipes" title="Permalink to this headline">¶</a></h3>
<p>The cool thing about domain sockets is that file descriptors can be exchanged
between processes by sending them over a domain socket. This allows processes
to hand off their I/O to other processes. Applications include load-balancing
servers, worker processes and other ways to make optimum use of CPU. libuv only
supports sending <strong>TCP sockets or other pipes</strong> over pipes for now.</p>
<p>To demonstrate, we will look at a echo server implementation that hands of
clients to worker processes in a round-robin fashion. This program is a bit
involved, and while only snippets are included in the book, it is recommended
to read the full code to really understand it.</p>
<p>The worker process is quite simple, since the file-descriptor is handed over to
it by the master.</p>
<p class="rubric">multi-echo-server/worker.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="highlight"><pre><span></span>
<span class="n">uv_loop_t</span> <span class="o">*</span><span class="n">loop</span><span class="p">;</span>
<span class="n">uv_pipe_t</span> <span class="n">queue</span><span class="p">;</span>
<span class="nb">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">uv_default_loop</span><span class="p">();</span>
<span class="hll">
</span><span class="hll">    <span class="n">uv_pipe_init</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">queue</span><span class="p">,</span> <span class="mi">1</span> <span class="o">/*</span> <span class="n">ipc</span> <span class="o">*/</span><span class="p">);</span>
</span><span class="hll">    <span class="n">uv_pipe_open</span><span class="p">(</span><span class="o">&amp;</span><span class="n">queue</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span>    <span class="n">uv_read_start</span><span class="p">((</span><span class="n">uv_stream_t</span><span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">queue</span><span class="p">,</span> <span class="n">alloc_buffer</span><span class="p">,</span> <span class="n">on_new_connection</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">uv_run</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="n">UV_RUN_DEFAULT</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p><code class="docutils literal notranslate"><span class="pre">queue</span></code> is the pipe connected to the master process on the other end, along
which new file descriptors get sent. It is important to set the <code class="docutils literal notranslate"><span class="pre">ipc</span></code>
argument of <code class="docutils literal notranslate"><span class="pre">uv_pipe_init</span></code> to 1 to indicate this pipe will be used for
inter-process communication! Since the master will write the file handle to the
standard input of the worker, we connect the pipe to <code class="docutils literal notranslate"><span class="pre">stdin</span></code> using
<code class="docutils literal notranslate"><span class="pre">uv_pipe_open</span></code>.</p>
<p class="rubric">multi-echo-server/worker.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29</pre></div></td><td class="code"><div class="highlight"><pre><span></span>void on_new_connection(uv_stream_t *q, ssize_t nread, const uv_buf_t *buf) {
    if (nread &lt; 0) {
        if (nread != UV_EOF)
            fprintf(stderr, &quot;Read error %s\n&quot;, uv_err_name(nread));
        uv_close((uv_handle_t*) q, NULL);
        return;
    }

    uv_pipe_t *pipe = (uv_pipe_t*) q;
<span class="hll">    if (!uv_pipe_pending_count(pipe)) {
</span>        fprintf(stderr, &quot;No pending count\n&quot;);
        return;
    }

<span class="hll">    uv_handle_type pending = uv_pipe_pending_type(pipe);
</span>    assert(pending == UV_TCP);

    uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop, client);
<span class="hll">    if (uv_accept(q, (uv_stream_t*) client) == 0) {
</span>        uv_os_fd_t fd;
        uv_fileno((const uv_handle_t*) client, &amp;fd);
        fprintf(stderr, &quot;Worker %d: Accepted fd %d\n&quot;, getpid(), fd);
        uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read);
    }
    else {
        uv_close((uv_handle_t*) client, NULL);
    }
}
</pre></div>
</td></tr></table></div>
<p>First we call <code class="docutils literal notranslate"><span class="pre">uv_pipe_pending_count()</span></code> to ensure that a handle is available
to read out. If your program could deal with different types of handles,
<code class="docutils literal notranslate"><span class="pre">uv_pipe_pending_type()</span></code> can be used to determine the type.
Although <code class="docutils literal notranslate"><span class="pre">accept</span></code> seems odd in this code, it actually makes sense. What
<code class="docutils literal notranslate"><span class="pre">accept</span></code> traditionally does is get a file descriptor (the client) from
another file descriptor (The listening socket). Which is exactly what we do
here. Fetch the file descriptor (<code class="docutils literal notranslate"><span class="pre">client</span></code>) from <code class="docutils literal notranslate"><span class="pre">queue</span></code>. From this point
the worker does standard echo server stuff.</p>
<p>Turning now to the master, let’s take a look at how the workers are launched to
allow load balancing.</p>
<p class="rubric">multi-echo-server/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">struct</span> <span class="n">child_worker</span> <span class="p">{</span>
    <span class="n">uv_process_t</span> <span class="n">req</span><span class="p">;</span>
    <span class="n">uv_process_options_t</span> <span class="n">options</span><span class="p">;</span>
    <span class="n">uv_pipe_t</span> <span class="n">pipe</span><span class="p">;</span>
<span class="p">}</span> <span class="o">*</span><span class="n">workers</span><span class="p">;</span>
</pre></div>
</td></tr></table></div>
<p>The <code class="docutils literal notranslate"><span class="pre">child_worker</span></code> structure wraps the process, and the pipe between the
master and the individual process.</p>
<p class="rubric">multi-echo-server/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">void</span> <span class="n">setup_workers</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">round_robin_counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="o">//</span> <span class="o">...</span>

    <span class="o">//</span> <span class="n">launch</span> <span class="n">same</span> <span class="n">number</span> <span class="n">of</span> <span class="n">workers</span> <span class="k">as</span> <span class="n">number</span> <span class="n">of</span> <span class="n">CPUs</span>
    <span class="n">uv_cpu_info_t</span> <span class="o">*</span><span class="n">info</span><span class="p">;</span>
    <span class="nb">int</span> <span class="n">cpu_count</span><span class="p">;</span>
    <span class="n">uv_cpu_info</span><span class="p">(</span><span class="o">&amp;</span><span class="n">info</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">cpu_count</span><span class="p">);</span>
    <span class="n">uv_free_cpu_info</span><span class="p">(</span><span class="n">info</span><span class="p">,</span> <span class="n">cpu_count</span><span class="p">);</span>

    <span class="n">child_worker_count</span> <span class="o">=</span> <span class="n">cpu_count</span><span class="p">;</span>

    <span class="n">workers</span> <span class="o">=</span> <span class="n">calloc</span><span class="p">(</span><span class="n">sizeof</span><span class="p">(</span><span class="n">struct</span> <span class="n">child_worker</span><span class="p">),</span> <span class="n">cpu_count</span><span class="p">);</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">cpu_count</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">struct</span> <span class="n">child_worker</span> <span class="o">*</span><span class="n">worker</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">workers</span><span class="p">[</span><span class="n">cpu_count</span><span class="p">];</span>
<span class="hll">        <span class="n">uv_pipe_init</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">worker</span><span class="o">-&gt;</span><span class="n">pipe</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span>
        <span class="n">uv_stdio_container_t</span> <span class="n">child_stdio</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
<span class="hll">        <span class="n">child_stdio</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_CREATE_PIPE</span> <span class="o">|</span> <span class="n">UV_READABLE_PIPE</span><span class="p">;</span>
</span><span class="hll">        <span class="n">child_stdio</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="p">(</span><span class="n">uv_stream_t</span><span class="o">*</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">worker</span><span class="o">-&gt;</span><span class="n">pipe</span><span class="p">;</span>
</span>        <span class="n">child_stdio</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_IGNORE</span><span class="p">;</span>
        <span class="n">child_stdio</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">UV_INHERIT_FD</span><span class="p">;</span>
        <span class="n">child_stdio</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">fd</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>

        <span class="n">worker</span><span class="o">-&gt;</span><span class="n">options</span><span class="o">.</span><span class="n">stdio</span> <span class="o">=</span> <span class="n">child_stdio</span><span class="p">;</span>
        <span class="n">worker</span><span class="o">-&gt;</span><span class="n">options</span><span class="o">.</span><span class="n">stdio_count</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>

        <span class="n">worker</span><span class="o">-&gt;</span><span class="n">options</span><span class="o">.</span><span class="n">exit_cb</span> <span class="o">=</span> <span class="n">close_process_handle</span><span class="p">;</span>
        <span class="n">worker</span><span class="o">-&gt;</span><span class="n">options</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
        <span class="n">worker</span><span class="o">-&gt;</span><span class="n">options</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="p">;</span>

        <span class="n">uv_spawn</span><span class="p">(</span><span class="n">loop</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">worker</span><span class="o">-&gt;</span><span class="n">req</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">worker</span><span class="o">-&gt;</span><span class="n">options</span><span class="p">);</span> 
        <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s2">&quot;Started worker </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">worker</span><span class="o">-&gt;</span><span class="n">req</span><span class="o">.</span><span class="n">pid</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>In setting up the workers, we use the nifty libuv function <code class="docutils literal notranslate"><span class="pre">uv_cpu_info</span></code> to
get the number of CPUs so we can launch an equal number of workers. Again it is
important to initialize the pipe acting as the IPC channel with the third
argument as 1. We then indicate that the child process’ <code class="docutils literal notranslate"><span class="pre">stdin</span></code> is to be
a readable pipe (from the point of view of the child). Everything is
straightforward till here. The workers are launched and waiting for file
descriptors to be written to their standard input.</p>
<p>It is in <code class="docutils literal notranslate"><span class="pre">on_new_connection</span></code> (the TCP infrastructure is initialized in
<code class="docutils literal notranslate"><span class="pre">main()</span></code>), that we accept the client socket and pass it along to the next
worker in the round-robin.</p>
<p class="rubric">multi-echo-server/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19</pre></div></td><td class="code"><div class="highlight"><pre><span></span>void on_new_connection(uv_stream_t *server, int status) {
    if (status == -1) {
        // error!
        return;
    }

    uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop, client);
<span class="hll">    if (uv_accept(server, (uv_stream_t*) client) == 0) {
</span>        uv_write_t *write_req = (uv_write_t*) malloc(sizeof(uv_write_t));
        dummy_buf = uv_buf_init(&quot;a&quot;, 1);
<span class="hll">        struct child_worker *worker = &amp;workers[round_robin_counter];
</span><span class="hll">        uv_write2(write_req, (uv_stream_t*) &amp;worker-&gt;pipe, &amp;dummy_buf, 1, (uv_stream_t*) client, NULL);
</span>        round_robin_counter = (round_robin_counter + 1) % child_worker_count;
    }
    else {
        uv_close((uv_handle_t*) client, NULL);
    }
}
</pre></div>
</td></tr></table></div>
<p>The <code class="docutils literal notranslate"><span class="pre">uv_write2</span></code> call handles all the abstraction and it is simply a matter of
passing in the handle (<code class="docutils literal notranslate"><span class="pre">client</span></code>) as the right argument. With this our
multi-process echo server is operational.</p>
<p>Thanks to Kyle for <a class="reference external" href="https://github.com/nikhilm/uvbook/issues/56">pointing out</a> that <code class="docutils literal notranslate"><span class="pre">uv_write2()</span></code> requires a non-empty
buffer even when sending handles.</p>
<hr class="docutils" />
<dl class="footnote brackets">
<dt class="label" id="id3"><span class="brackets"><a class="fn-backref" href="#id2">1</a></span></dt>
<dd><p>In this section domain sockets stands in for named pipes on Windows as
well.</p>
</dd>
</dl>
</div>
</div>
</div>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../index.html">
              <img class="logo" src="../_static/logo.png" alt="Logo"/>
            </a></p>
  <h3><a href="../index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Processes</a><ul>
<li><a class="reference internal" href="#spawning-child-processes">Spawning child processes</a></li>
<li><a class="reference internal" href="#changing-process-parameters">Changing process parameters</a><ul>
<li><a class="reference internal" href="#change-execution-directory">Change execution directory</a></li>
<li><a class="reference internal" href="#set-environment-variables">Set environment variables</a></li>
<li><a class="reference internal" href="#option-flags">Option flags</a></li>
</ul>
</li>
<li><a class="reference internal" href="#detaching-processes">Detaching processes</a></li>
<li><a class="reference internal" href="#sending-signals-to-processes">Sending signals to processes</a></li>
<li><a class="reference internal" href="#signals">Signals</a></li>
<li><a class="reference internal" href="#child-process-i-o">Child Process I/O</a></li>
<li><a class="reference internal" href="#pipes">Pipes</a><ul>
<li><a class="reference internal" href="#parent-child-ipc">Parent-child IPC</a></li>
<li><a class="reference internal" href="#arbitrary-process-ipc">Arbitrary process IPC</a></li>
<li><a class="reference internal" href="#sending-file-descriptors-over-pipes">Sending file descriptors over pipes</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="threads.html"
                        title="previous chapter">Threads</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="eventloops.html"
                        title="next chapter">Advanced event loops</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/guide/processes.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" />
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="eventloops.html" title="Advanced event loops"
             >next</a> |</li>
        <li class="right" >
          <a href="threads.html" title="Threads"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">libuv 1.31.0 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../guide.html" >User guide</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">Processes</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2014-present, libuv contributors.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
    </div>
  </body>
</html>